#include "screen.h"
#include "system.h"
#include "io.h"


void puts(char *string)
{
    while (*string != 0x00)
    {
        putc(*string);
        string++;
    }
}

void scroll(int rows)
{
    char *video, *tmp;
    general_state_descriptor_block* gsdb = (general_state_descriptor_block*)0x1002;

    for (video = (char *) SCREEN_MEMORY; video < (char *)SCREEN_MEMORY_LIMIT; video += 2)
    {
    	tmp = (char *) (video + rows * 160);

        if (tmp < (char *) SCREEN_MEMORY_LIMIT)
        {
        	*video = *tmp;
        	*(video + 1) = *(tmp + 1);
        }
        else
        {
        	*video = 0;
        	*(video + 1) = gsdb->text_attr;
        }
	}

    gsdb->cursorY -= rows;
    
    if (gsdb->cursorY < 0)
    	gsdb->cursorY = 0;
    	
    update_cursor(gsdb->cursorX, gsdb->cursorY);
}

void putc(char character)
{
	general_state_descriptor_block* gsdb = (general_state_descriptor_block*)0x1002;
	
    char *video;
    
    if (character == 13)
    {
        gsdb->cursorX = 0;
    }
    else if (character == 10)
    {
    	gsdb->cursorX = 0;
        gsdb->cursorY++;
    }
    else
    {
    	video = (char *)(SCREEN_MEMORY + 2 * gsdb->cursorX + 160 * gsdb->cursorY);
    	video[0] = character;
    	video[1] = gsdb->text_attr;
    	gsdb->cursorX++;
    }
    
    if (gsdb->cursorX >= CONSOLE_WIDTH)
    {
        gsdb->cursorX = 0;
        gsdb->cursorY++;
    }
    
    
    if (gsdb->cursorY >= CONSOLE_HEIGHT)
        scroll(1);
        
    update_cursor(gsdb->cursorX, gsdb->cursorY);
    
}


void set_attr(char attr)
{
	general_state_descriptor_block* gsdb = (general_state_descriptor_block*)0x1002;
	gsdb->text_attr = attr;
}


void set_color(char attr)
{
	general_state_descriptor_block* gsdb = (general_state_descriptor_block*)0x1002;
	gsdb->text_attr ^= ((attr ^ gsdb->text_attr) & 0x0F);
}


void set_background(char attr)
{
	general_state_descriptor_block* gsdb = (general_state_descriptor_block*)0x1002;
	gsdb->text_attr ^= ((attr ^ gsdb->text_attr) & 0xF0);
}


void update_cursor(char x, char y)
{
	unsigned short position=x + y*80;
	
    outb(0x3D4, 0x0F);
    outb(0x3D5, (unsigned char)(position&0xFF));
    outb(0x3D4, 0x0E);
    outb(0x3D5, (unsigned char )((position>>8)&0xFF));
}